package qu.wssecurity.reasoner;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import com.hp.hpl.jena.ontology.Individual;
import com.hp.hpl.jena.ontology.ObjectProperty;
import com.hp.hpl.jena.ontology.OntClass;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Selector;
import com.hp.hpl.jena.rdf.model.SimpleSelector;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.util.iterator.ExtendedIterator;
import com.hp.hpl.jena.vocabulary.XSD;


public class Main {
static String namespace = "http://www.ontologie.fr/Ontology#";

static OntModel RequierementAli()//Creating Ali Ontology Requirements	
{	

	//Creation of the Ontology
	OntModel Req;
	
	Req = ModelFactory.createOntologyModel ();
	Req.createOntology (namespace);
	//Creation of the class Security
	OntClass Security = Req.createClass (namespace + "Security");
	//Creation of the subclasses Encryption, DigitalSignature and Protocol
	OntClass Encryption = Req.createClass (namespace + "Encryption");
	OntClass DigitalSignature = Req.createClass (namespace + "DigitalSignature");
	OntClass Protocol = Req.createClass (namespace + "Protocol");
    Security.addSubClass(Encryption);Security.addSubClass(DigitalSignature);Security.addSubClass(Protocol);
    Encryption.addDisjointWith(DigitalSignature);Encryption.addDisjointWith(Protocol); 
    DigitalSignature.addDisjointWith(Protocol);DigitalSignature.addDisjointWith(Encryption);
    Protocol.addDisjointWith(DigitalSignature);Protocol.addDisjointWith(Encryption);
    //Creation of the properties HasImportance
    ObjectProperty HasImportance = Req.createObjectProperty (namespace + "HasImportance");
    HasImportance.setDomain (Security);
    HasImportance.setDomain(XSD.xdouble);
    //Assigning Importance
    Statement statement = Req.createLiteralStatement(Encryption, HasImportance, 0.6);
    Req.add(statement);
    statement = Req.createLiteralStatement(DigitalSignature, HasImportance, 0.3);
    Req.add(statement);
    statement = Req.createLiteralStatement(Protocol, HasImportance, 0.1);
    Req.add(statement);
  //Creatig object for subclasses Encryption, DigitalSignature and Protocol
    Individual Pailler=DigitalSignature.createIndividual(namespace + "Pailler");
    Individual ElGamal=DigitalSignature.createIndividual(namespace + "ElGamal");
    Individual xml_Enc=Encryption.createIndividual(namespace + "xml_Enc");
    Individual CAST5=Encryption.createIndividual(namespace + "CAST5");
    Individual IPsec=Protocol.createIndividual(namespace + "IPsec");
    // Add Preferences to object with HasPreference
    ObjectProperty HasPreference = Req.createObjectProperty (namespace + "HasPreference");
    HasPreference.setDomain (Security);
    HasPreference.setDomain(XSD.xint);
    statement = Req.createLiteralStatement(Pailler, HasPreference, 3);
    Req.add(statement);
    statement = Req.createLiteralStatement(ElGamal, HasPreference, 5);
    Req.add(statement);
        statement = Req.createLiteralStatement(xml_Enc, HasPreference, 5);
    Req.add(statement);
    statement = Req.createLiteralStatement(CAST5, HasPreference, 3);
    Req.add(statement);
    statement = Req.createLiteralStatement(IPsec, HasPreference, 5);
    Req.add(statement);
return Req;
}
static OntModel RequierementSarah()//Creating Ali Ontology Requirements	
{	
//Creation of the Ontology
	OntModel Req;
	Req = ModelFactory.createOntologyModel ();
	Req.createOntology (namespace);
	//Creation of the class Security
	OntClass Security = Req.createClass (namespace + "Security");
	//Creation of the subclasses Encryption, DigitalSignature and Protocol
	OntClass Encryption = Req.createClass (namespace + "Encryption");
	OntClass DigitalSignature = Req.createClass (namespace + "DigitalSignature");
	OntClass Protocol = Req.createClass (namespace + "Protocol");
    Security.addSubClass(Encryption);Security.addSubClass(DigitalSignature);Security.addSubClass(Protocol);
    Encryption.addDisjointWith(DigitalSignature);Encryption.addDisjointWith(Protocol); 
    DigitalSignature.addDisjointWith(Protocol);DigitalSignature.addDisjointWith(Encryption);
    Protocol.addDisjointWith(DigitalSignature);Protocol.addDisjointWith(Encryption);
    //Creation of the properties HasImportance
    ObjectProperty HasImportance = Req.createObjectProperty (namespace + "HasImportance");
    HasImportance.setDomain (Security);
    HasImportance.setDomain(XSD.xdouble);
    //Assigning Importance
    Statement statement = Req.createLiteralStatement(Encryption, HasImportance, 0.6);
    Req.add(statement);
    statement = Req.createLiteralStatement(DigitalSignature, HasImportance, 0.3);
    Req.add(statement);
    statement = Req.createLiteralStatement(Protocol, HasImportance, 0.1);
    Req.add(statement);
  //Creatig object for subclasses Encryption, DigitalSignature and Protocol
    Individual 	RSAPSS=DigitalSignature.createIndividual(namespace + "RSA-PSS"); 
    Individual 	DiffieHellman=DigitalSignature.createIndividual(namespace + "Diffie-Hellman");
    Individual Pailler=DigitalSignature.createIndividual(namespace + "Pailler");
    Individual Schnorr=DigitalSignature.createIndividual(namespace + "Schnorr");
    Individual AES=Encryption.createIndividual(namespace + "AES");
    Individual DES3=Encryption.createIndividual(namespace + "3DES");
    Individual RC4=Encryption.createIndividual(namespace + "RC4");
    Individual PPP=Protocol.createIndividual(namespace + "PPP");
    Individual PGP=Protocol.createIndividual(namespace + "PGP");
    Individual TLS=Protocol.createIndividual(namespace + "TLS");
    // Add Preferences to object with HasPreference
    ObjectProperty HasPreference = Req.createObjectProperty (namespace + "HasPreference");
    HasPreference.setDomain (Security);
    HasPreference.setDomain(XSD.xint);
    statement = Req.createLiteralStatement(RSAPSS, HasPreference, 5);
    Req.add(statement);
    statement = Req.createLiteralStatement(DiffieHellman, HasPreference, 5);
    Req.add(statement);
    statement = Req.createLiteralStatement(Pailler, HasPreference, 3);
    Req.add(statement);
    statement = Req.createLiteralStatement(Schnorr, HasPreference, 3);
    Req.add(statement);
    statement = Req.createLiteralStatement(AES, HasPreference, 5);
    Req.add(statement);
    statement = Req.createLiteralStatement(DES3, HasPreference, 3);
    Req.add(statement);
    statement = Req.createLiteralStatement(RC4, HasPreference, 1);
    Req.add(statement);
    statement = Req.createLiteralStatement(PPP, HasPreference, 3);
    Req.add(statement);
    statement = Req.createLiteralStatement(PGP, HasPreference, 5);
    Req.add(statement);
    statement = Req.createLiteralStatement(TLS, HasPreference, 5);
    Req.add(statement);
return Req;
}



static OntModel Capabilities()	
{
	//Creation of the Ontology
	   OntModel Cap;
	    Cap = ModelFactory.createOntologyModel ();
		Cap.createOntology (namespace);
		//Creation of the class Security
		OntClass Security = Cap.createClass (namespace + "Security");
		//Creation of the subclasses Encryption, DigitalSignature and Protocol
		OntClass Encryption = Cap.createClass (namespace + "Encryption");
		OntClass DigitalSignature = Cap.createClass (namespace + "DigitalSignature");
		OntClass Protocol = Cap.createClass (namespace + "Protocol");
	    Security.addSubClass(Encryption);Security.addSubClass(DigitalSignature);Security.addSubClass(Protocol);
	    Encryption.addDisjointWith(DigitalSignature);Encryption.addDisjointWith(Protocol); 
	    DigitalSignature.addDisjointWith(Protocol);DigitalSignature.addDisjointWith(Encryption);
	    Protocol.addDisjointWith(DigitalSignature);Protocol.addDisjointWith(Encryption);
	    
	  //Creatig object for subclasses Encryption, DigitalSignature and Protocol
	    Individual 	RSAPSS=DigitalSignature.createIndividual(namespace + "RSA-PSS"); 
	    Individual Pailler=DigitalSignature.createIndividual(namespace + "Pailler");
	    Individual AES=Encryption.createIndividual(namespace + "AES");
	    Individual CAST5=Encryption.createIndividual(namespace + "CAST5");
	    Individual Blofish=Encryption.createIndividual(namespace + "Blofish");
	    Individual IKE=Protocol.createIndividual(namespace + "IKE");
	    Individual PGP=Protocol.createIndividual(namespace + "PGP");
	    Individual Kerberos=Protocol.createIndividual(namespace + "Kerberos");
	    	

	    return Cap;
}	

	
	public static void main(String[] args) 
	
	
	{
		String Path=new String("C:/Users/huhu/Desktop/Security.owl");
		OntModel Requiremets, Capabilities;
		Capabilities= Capabilities();
		Requiremets=RequierementSarah();
		Print(Requiremets, Path);
		System.out.printf ("Final Score = %3.1f%n", Matching(Requiremets, Capabilities));	
	}

static double  Matching(OntModel Req, OntModel Cap)
{

   ObjectProperty Importance=Req.getObjectProperty(namespace+"HasImportance");
   ObjectProperty Preference=Req.getObjectProperty(namespace+"HasPreference");
   Selector selector = new SimpleSelector(null, Importance,(RDFNode) null);
   StmtIterator ImpIter = Req.listStatements(selector);
   ExtendedIterator IndIter = Cap.listIndividuals();
   java.util.List<Individual> CapList= IndIter.toList();
   double Score=0;	
   int Max=0;
 while (ImpIter.hasNext()) 
  {
	Statement stmImp= ImpIter.nextStatement();  
	Resource sub=stmImp.getSubject();
	ExtendedIterator P = Req.listIndividuals(sub);
	java.util.List<Individual> SList= P.toList();
	selector = new SimpleSelector(null, Preference,(RDFNode) null);
	StmtIterator PrefIter = Req.listStatements(selector);	 
	while (PrefIter.hasNext())
	{
		Statement stmPref= PrefIter.nextStatement();
		
		Resource subject=stmPref.getSubject();
		          
		if( (SList.contains(subject))&&(CapList.contains(subject))&&
				(Max<stmPref.getObject().asLiteral().getInt()))
			Max=stmPref.getObject().asLiteral().getInt();
	}
	Score=Score+Max*stmImp.getObject().asLiteral().getDouble();
	Max=0;	
  }
 return Score;
}


static void Print(OntModel O, String s)
{
FileOutputStream fichierSortie = null;
try {
	fichierSortie = new FileOutputStream (new File (s));
}
catch (FileNotFoundException ex) {
	
}
O.write (fichierSortie);

}	

}


